#include <cstring>

#include "KmyTextLayer.h"
#include "../KmyResourceManager.h"
#include "../KmyAlgorithm.h"
#include "../KmyMath.h"
#include "../KmyIDebug.h"

KmyTextLayer::KmyTextLayer(int w, int h, int rowheight)
{
    this->width = w;
    this->height = h;
    this->width_p = 1<<getSmallest2exp(w);
    this->height_p = 1<<getSmallest2exp(h);
    data16 = new u16[this->width_p*this->height_p];
    id = KmyNode::createID();
//    KmyResourceManager *krm = KmyResourceManager::getInstance();
//    font = krm->getFont();
//    string texname("textlayer");
//    texname = texname+intToString(id);
    tex = new KmyITexture(KmyITexture::TEXTURE_MODE_ARGB4,
                          (const u8*)data16, width_p, height_p, true);

    this->row_height = rowheight;
    max_row = h/row_height;
    view_ranges = new St_vrange[max_row];
    for (int i=0; i<max_row; i++){
        view_ranges[i].x = 0;
        view_ranges[i].y = i*this->row_height;
        view_ranges[i].h = this->row_height;
        view_ranges[i].w = 0;
        view_ranges[i].max_w = 0;
    }
    cur_rect = NULL;
    speed = 10;
    delay = 0;
    jumpy = new int[speed];
    for (int i=0; i<speed; i++){
        jumpy[i]=-i;
    }

//    max_range.x = 0;
//    max_range.y = 0;
//    max_range.w = this->width;
//    max_range.h = this->height;
}

int KmyTextLayer::getNodeType(){
    return KmyNode::NODE_TYPE_TEXTLAYER;
}

KmyTextLayer::~KmyTextLayer(){
    delete tex;
    delete[] data16;
    delete[] view_ranges;
    delete[] jumpy;
    delete[] bt;
    ST_VectorNode *n = char_list.getHead();
    while (n!=NULL){
        St_Rect* node = (St_Rect*)(n->value);
        delete node;
        n = n->next;
    }
}

void KmyTextLayer::initialize(){
    font = KmyResourceManager::getInstance()->getFont();
    clear();
    pos_x = 0;
    cur_row = 0;

    color_bone=0xffff;
    color_skin=0x000f;

    bt = new int[font->mbcs_height];
    tex->is_changed = true;
}

void KmyTextLayer::finalize(){
    delete[] data16;
    data16 = NULL;
    ST_VectorNode *p = char_list.getHead();
    while (p!=NULL){
        St_Rect* node = (St_Rect*)(p->value);
        delete node;
        p = p->next;
    }
    char_list.clear();
    cur_rect = NULL;
    delete tex;
}

void KmyTextLayer::clear(){
    int* p = (int*)data16;
    for (int i=0; i<width_p*height>>1; i++){
        *p++ = 0x00000000;
    };
    tex->is_changed = true;
    pos_x = 0;
    cur_row = 0;
    ST_VectorNode *n = char_list.getHead();
    while (n!=NULL){
        St_Rect* node = (St_Rect*)(n->value);
        delete node;
        n = n->next;
    }
    char_list.clear();
    cur_rect = NULL;
    delay = 0;
}

int KmyTextLayer::putUtf8String(const u8 *str, int space, int height){
    int total_offset = 0;
    u16 ucs2code = 0;
    int offset = 0;
    switch (outward){
    case KmyTextLayer::OUTWARD_TYPE_SHADOW:
        space+=1;
        break;
    case KmyTextLayer::OUTWARD_TYPE_SURROUND:
        space+=2;
        break;
    case KmyTextLayer::OUTWARD_TYPE_NORMAL:
        break;
    }

    bool result;
    do{
        offset = utf8ToUcs2(str+total_offset, ucs2code);
        if (offset==-1){
            return -1;
        }
        if (ucs2code==0){
            break;
        }
        result = putUcs2Char(ucs2code, space, height);
        if (result){
            total_offset+=offset;
        }
    }while(result);
    tex->is_changed = true;
    return total_offset;
}

int KmyTextLayer::putUcs2String(const u16 *str, int space, int height){
    switch (outward){
    case KmyTextLayer::OUTWARD_TYPE_SHADOW:
        space+=1;
        break;
    case KmyTextLayer::OUTWARD_TYPE_SURROUND:
        space+=2;
        break;
    case KmyTextLayer::OUTWARD_TYPE_NORMAL:
        break;
    }
    return putUcs2String_1(str, space, height);
}

bool KmyTextLayer::putUcs2Char(u16 uc, int space, int height){
    if (uc == '\n'){
//        view_ranges[cur_row].max_w = pos_x;
        pos_x = 0;
        cur_row++;
        if (cur_row<max_row){
            view_ranges[cur_row].max_w = pos_x;
        }
        return true;
    }
    int font_width;
    int font_height;
    int font_pix_width;
    int fw;
    int fh;
    if (uc<128){
        font_width = font->ascii_width;
        font_height = font->ascii_height;
    }else{
        font_width = font->mbcs_width;
        font_height = font->mbcs_height;
    }
    if (font->is_with_width){
        font_pix_width = font->getUcs2Width(uc);
    }else{
        font_pix_width = font_width;
    }
    float size = (float)height/font_height;
    fw = kmy_round(font_pix_width*size);
    fh = kmy_round(font_height*size);

    int pos_y = cur_row*row_height + (row_height-fh);
    if (pos_x+space+fw>this->width){
        if (cur_row>=max_row-1){
            return false;
        }else{
            pos_x = 0;
            pos_y+=row_height;
            cur_row++;
        }
    }

    St_charrect *rect = new St_charrect;

    char_list.addValue((void*)rect);
    rect->x = pos_x;
    rect->y = cur_row*row_height;
    rect->w = fw+space;
    rect->h = row_height;
    rect->row = cur_row;

    drawCharResize2(uc, font_width, font_height, pos_x, pos_y, size);

    pos_x+=(space+fw);
    view_ranges[cur_row].max_w = pos_x;
    return true;
}


int KmyTextLayer::putUcs2String_1(const u16 *str, int space, int height){
    int total_offset = 0;
    // 默认 LittleEndian
    u16 ucs2code;
    int offset = 1;
    bool result;
    do{
        ucs2code = str[total_offset];
        if (ucs2code==0){
            break;
        }
        result = putUcs2Char(ucs2code, space, height);
        if (result){
            total_offset+=offset;
        }
    }while(result);
    tex->is_changed = true;
    return total_offset;
}

int KmyTextLayer::putUcs2String_2(const u16 *str, int posx, int posy, int space, int height){
    int total_offset = 0;
    // 默认 LittleEndian
    u16 ucs2code;
    int offset = 1;
    bool result;
    do{
        ucs2code = str[total_offset];
        if (ucs2code==0){
            break;
        }
        result = putUcs2Char_2(ucs2code, posx, posy, height);
        if (result){
            total_offset+=offset;
        }
        posx+=space;
    }while(result);
    tex->is_changed = true;
    return total_offset;
}

bool KmyTextLayer::putUcs2Char_2(u16 uc, int &posx, int &posy, int height){
//    if (uc == '\n'){
//        posx16 = 0;
//        cur_row++;
//        return true;
//    }
    int font_width;
    int font_height;
    int font_pix_width;
    int fw;
    int fh;
    if (uc<128){
        font_width = font->ascii_width;
        font_height = font->ascii_height;
    }else{
        font_width = font->mbcs_width;
        font_height = font->mbcs_height;
    }
    if (font->is_with_width){
        font_pix_width = font->getUcs2Width(uc);
//        font_pix_width = font_width;
//        src+=4;
    }else{
        font_pix_width = font_width;
    }
    float size = (float)height/font_height;
    fw = kmy_round(font_pix_width*size);
    fh = kmy_round(font_height*size);
    if (posx+fw>this->width){
        return false;
    }

    drawCharResize2(uc, font_width, font_height, posx, posy, size);

    posx+=fw;
    return true;
}

int KmyTextLayer::utf8ToUcs2(const u8 *str, u16 &ucs2code){
    const u8 *p = str;
    if (*p == 0 || *p=='\n'){
        ucs2code = *p;
        return 1;
    }else if (*p<32){
        ucs2code = 32;
        return 1;
    }else if (*p<0x80){
        // 单字节
        ucs2code = *p;
        return 1;
//    }else if ((*p & 0xF8) == 0xF0){
//        // 四字节超过了双字节的范围，不计
//        u16 c4 = *p & 7;
//        p++;
//        u16 c3 = *p & 0x3F;
//        p++;
//        u16 c2 = *p & 0x3F;
//        p++;
//        u16 c1 = *p & 0x3F;
//        ucs2code = (c4<<18)|(c3<<12)|(c2<<6)|c1;
//        return 4;
    }else if ((*p & 0xF0) == 0xE0){
        // 三字节
        u16 c3 = *p & 0x0F;
        p++;
        u16 c2 = *p & 0x3F;
        p++;
        u16 c1 = *p & 0x3F;
        ucs2code = (c3<<12)|(c2<<6)|c1;
        return 3;
    }else if ((*p & 0xE0) == 0xC0){
        // 二字节
        u16 c2 = *p & 0x1F;
        p++;
        u16 c1 = *p & 0x3F;
        ucs2code = (c2<<6)|c1;
        return 2;
    }else{
        // 错误编码
        return -1;
    }
}

void KmyTextLayer::setColor(u16 bone, u16 skin){
//    color[0]=0;
//    color[color_num-1]=bone;
//    u16 a = skin&0x000f;
//    u16 rgb = skin&0xfff0;
//    for (int i= color_num-2; i>0; i--){
//        int a2=a*i/(color_num-2);
//        color[i] = rgb|a2;
//    }
    color_bone = bone;
    color_skin = skin;
}

//void KmyTextLayer::setColorTable(u16 color1, u16 color2, u16 color3){
//    color[1] = color1;
//    color[2] = color2;
//    color[3] = color3;
//}

void KmyTextLayer::setOutward(int type){
    outward = type;
}

void KmyTextLayer::setSpeed(int s){
    speed = s;
}

int KmyTextLayer::getUtf8StrLength(const u8 *str){
    const u8 *p = str;
    int length = 0;
    while(*p!=0){
        if ((*p&0xC0) != 0x80){
            length++;
        }
        p++;
    }
    return length;
}

int KmyTextLayer::getUcs2StrLength(const u16 *str){
    u16 *p = (u16*)str;
    int length = 0;
    while(*p!=0){
        length++;
        p++;
    }
    return length;
}

//int KmyTextLayer::getUtf8StrWidth(const u8 *str){
//    const u8 *p = str;
//    int length = 0;
//    while(*p!=0){
//        if ((*p&0xC0) != 0x80){
//            if (*p<0x80){
//                length+=font->ascii_width;
//            }else{
//                length+=font->mbcs_width;
//            }
//        }
//        p++;
//    }
//    return length;
//}

int KmyTextLayer::getUcs2StrWidth(const u16 *str, int space, int height){
    u16 *p = (u16*)str;
    int length = 0;
    float size = (float)height/font->mbcs_height;
    while(*p!=0){
        if (font->is_with_width){
            length+=kmy_round(font->getUcs2Width(*p)*size);
        }else{
            if (*p<128){
                length+=kmy_round(font->ascii_width*size);
            }else{
                length+=kmy_round(font->mbcs_width*size);
            }
        }
        length+=space;

        p++;
    }
    return length;
}


/**
 *  首先要获取两字符串的长度（标准大小）
 *  然后计算合适的字间距
 *  分别画出
 */
void KmyTextLayer::putUtf8Phonetic(const u8 *main, const u8 *phn, int space, int height1, int height2){
    int length;
    u16* main_ucs2 = utf8ToUcs2Str(main, length);
    u16* phn_ucs2 = utf8ToUcs2Str(phn, length);
    putUcs2Phonetic(main_ucs2, phn_ucs2, space, height1, height2);
    delete main_ucs2;
    delete phn_ucs2;
}
void KmyTextLayer::putUtf8Phonetic2(const u8 *main, const u8 *phn, int space, int height1, int height2){
    int length;
    u16* main_ucs2 = utf8ToUcs2Str(main, length);
    u16* phn_ucs2 = utf8ToUcs2Str(phn, length);
    putUcs2Phonetic2(main_ucs2, phn_ucs2, space, height1, height2);
    delete main_ucs2;
    delete phn_ucs2;
}

void KmyTextLayer::putUcs2Phonetic(const u16 *main, const u16 *phn, int space, int height1, int height2){
    int main_s = space;
    int phn_s = 0;
    switch (outward){
    case KmyTextLayer::OUTWARD_TYPE_SHADOW:
        main_s+=1;
        phn_s+=1;
        break;
    case KmyTextLayer::OUTWARD_TYPE_SURROUND:
        main_s+=2;
        phn_s+=2;
        break;
    case KmyTextLayer::OUTWARD_TYPE_NORMAL:
        break;
    }
    int main_length = getUcs2StrLength(main);
    int phn_length = getUcs2StrLength(phn);
    int main_width = getUcs2StrWidth(main, main_s, height1);
    int phn_width = getUcs2StrWidth(phn, phn_s, height2);
    if (main_width>phn_width){
        phn_s = phn_s+(main_width-phn_width)/(phn_length+1);
    }
    else if (main_width<phn_width){
        main_s = main_s+(phn_width-main_width)/(main_length+1);
    }
    int temp_x = pos_x;
    int temp_y = (cur_row+1)*row_height-height1-height2;
    pos_x+=main_s-space;
    putUcs2String_1(main, main_s, height1);
    temp_x+=phn_s;
    putUcs2String_2(phn, temp_x, temp_y, phn_s, height2);
}

void KmyTextLayer::putUcs2Phonetic2(const u16 *main, const u16 *phn, int space, int height1, int height2){
    int main_s = space;
    int phn_s = 0;
    switch (outward){
    case KmyTextLayer::OUTWARD_TYPE_SHADOW:
        main_s+=1;
        phn_s+=1;
        break;
    case KmyTextLayer::OUTWARD_TYPE_SURROUND:
        main_s+=2;
        phn_s+=2;
        break;
    case KmyTextLayer::OUTWARD_TYPE_NORMAL:
        break;
    }
    int main_width = getUcs2StrWidth(main, main_s, height1);
    int phn_width = getUcs2StrWidth(phn, phn_s, height2);
    if (main_width+pos_x>this->width
            || phn_width+pos_x>this->width){
        if (cur_row>=max_row-1){
            return;
        }
        pos_x = 0;
        cur_row++;
    }
    int temp_x = pos_x;
    int temp_y = (cur_row+1)*row_height-height1-height2;
    if (main_width<phn_width){
        St_charrect *rect = new St_charrect;

        char_list.addValue((void*)rect);
        rect->x = pos_x;
        rect->y = cur_row*row_height;
        rect->w = (phn_width-main_width)/2;
        rect->h = row_height;
        rect->row = cur_row;

        pos_x += (phn_width-main_width)/2;

    }
    if (main_width>phn_width){
        temp_x += (main_width-phn_width)/2;
    }
    putUcs2String_1(main, main_s, height1);
    if (main_width<phn_width){
        St_charrect *rect = new St_charrect;

        char_list.addValue((void*)rect);
        rect->x = pos_x;
        rect->y = cur_row*row_height;
        rect->w = (phn_width-main_width)/2;
        rect->h = row_height;
        rect->row = cur_row;

        pos_x += (phn_width-main_width)/2;
    }
    putUcs2String_2(phn, temp_x, temp_y, phn_s, height2);
}

void KmyTextLayer::putUtf8Ruby(const u8 *phn){
    int length;
    u16* phn_ucs2 = utf8ToUcs2Str(phn, length);
    int phn_s = 0;
    switch (outward){
    case KmyTextLayer::OUTWARD_TYPE_SHADOW:
        phn_s+=1;
        break;
    case KmyTextLayer::OUTWARD_TYPE_SURROUND:
        phn_s+=2;
        break;
    case KmyTextLayer::OUTWARD_TYPE_NORMAL:
        break;
    }
    int temp_y = (cur_row+1)*row_height-1.6*font->mbcs_height;
    putUcs2String_2(phn_ucs2, pos_x, temp_y, phn_s, 8);
}

u16* KmyTextLayer::utf8ToUcs2Str(const u8 *str, int &length){
    length = getUtf8StrLength(str);
    u16 *ucs2 = new u16[length+1];
    u16 uc = 0;
    int total_offset = 0;
    int offset = 0;
    for (int i=0; i<length; i++){
        offset = utf8ToUcs2(str+total_offset, uc);
        ucs2[i]=uc;
        total_offset+=offset;
    }
    ucs2[length]=0;
    return ucs2;
}

bool KmyTextLayer::isIdle(){
    if (cur_rect==NULL){
        return true;
    }
    return false;
}

void KmyTextLayer::logic(){
    if (cur_rect!=NULL){
        if (delay>0){
            delay--;
        }else{
            delay = speed;
            St_vrange *p = &view_ranges[cur_rect->row];
            p->w = cur_rect->x + cur_rect->w;
            delete cur_rect;
            cur_rect = NULL;
            is_updated = true;
        }
    }
    if (char_list.getSize()>0 && cur_rect==NULL){
        ST_VectorNode *head = char_list.getHead();
        cur_rect = (St_charrect*)(head->value);
        char_list.removeNode(head);
        is_updated = true;
    }
}

void KmyTextLayer::immediateOver(){
    char_list.clear();
    cur_rect = NULL;
    for (int i=0; i<max_row; i++){
        view_ranges[i].w = view_ranges[i].max_w;
    }
    is_updated = true;
}

void KmyTextLayer::render(KmyICanvas *screen){
    if (drawtask==NULL || is_updated){
        int frag_num = 0;
        for (int i=0; i<max_row; i++){
            if (view_ranges[i].w>0){
                frag_num++;
            }
        }
        if (cur_rect!=NULL){
            frag_num++;
        }

        if (frag_num==0){
            return;
        }
        St_Rect* srects = new St_Rect[frag_num];
        St_Rect2* drects = new St_Rect2[frag_num];
        int t=0;
        for (int i=0; i<max_row; i++){
            if (view_ranges[i].w>0){
                srects[t].x = view_ranges[i].x;
                srects[t].y = view_ranges[i].y;
                srects[t].w = view_ranges[i].w;
                srects[t].h = view_ranges[i].h;
                drects[t].x = getGlobalX();
                drects[t].y = getGlobalY()+view_ranges[i].y;
                drects[t].w = view_ranges[i].w;
                drects[t].h = view_ranges[i].h;
                drects[t].flip = 0;
                t++;
            }
        }
        if (cur_rect!=NULL){
            srects[t].x = cur_rect->x;
            srects[t].y = cur_rect->y;
            srects[t].w = cur_rect->w;
            srects[t].h = cur_rect->h;
            drects[t].x = getGlobalX()+cur_rect->x;
            drects[t].y = getGlobalY()+cur_rect->y+jumpy[delay];
            drects[t].w = cur_rect->w;
            drects[t].h = cur_rect->h;
            drects[t].flip = 0;
        }
        if (drawtask==NULL){
            drawtask = screen->addDrawTaskMultiImage(tex,
                                      frag_num, srects, drects,
                                      getGlobalZ(), 1.0f, 0);
        }else{
            // update drawtask
            drawtask->updatePlural(frag_num, srects, drects,
                                   getGlobalZ(), 1.0f, 0);
            is_updated = false;
            screen->addDrawTask(drawtask);
        }
        delete[] srects;
        delete[] drects;
    }else{
        screen->addDrawTask(drawtask);
    }
}

void KmyTextLayer::getEndPosition(int &x, int &y){
    if (pos_x==0 && cur_row>0){
        x = view_ranges[cur_row-1].max_w;
        y = view_ranges[cur_row-1].y;
    }else{
        x = pos_x>>4;
        y = cur_row*row_height;
    }
}

bool KmyTextLayer::testPageChange_Utf8(const u8 *str, int space, int size){
    int length;
    u16* ucs2str = utf8ToUcs2Str(str, length);
    bool result = testPageChange_Ucs2(ucs2str, space, size);
    delete ucs2str;
    return result;
}

bool KmyTextLayer::testPageChange_Ucs2(const u16 *str, int space, int size){
    int temp_posx = pos_x;
    int temp_cur_row = cur_row;
    int font_pix_width;
    int fw;
    u16 *p = (u16*)str;
    while(*p!=0){
        if (font->is_with_width){
            font_pix_width = font->getUcs2Width(*p);
        }else{
            if (*p<128){
                font_pix_width = font->ascii_width;
            }else{
                font_pix_width = font->mbcs_width;
            }
        }
        fw = kmy_round(font_pix_width*size);
        if (temp_posx+space+fw>this->width && temp_cur_row>=max_row-1){
            return true;
        }
        if (temp_posx+space+fw>this->width){
            temp_posx = 0;
            temp_cur_row++;
        }
        temp_posx+=(space+fw);
        p++;
    }
    return false;
}

void KmyTextLayer::drawCharResize2(u16 uc,
                               int font_width, int font_height,
                               int posx, int posy, float size){
    KmyIDebug *debuger = KmyIDebug::getInstance();
    u8* src_font_buff = font->getFontBuff(uc);
    int fw = kmy_roundup(font_width*size);
    int fh = kmy_roundup(font_height*size);
    u16 *resized_font = new u16[fw*fh];
    memset(resized_font, 0, fw*fh*2);

    for (int i=0; i<font_height; i++){
        bt[i] = i*size;
    }
    for (int i=0; i<font_height; i++){
        for (int j=0; j<font_width; j++){
            u16* t = &resized_font[bt[i]*fw+bt[j]];
            u8 ts = src_font_buff[i*font_width+j];
            if (ts!=0){
                *t+=0x0101;
            }else{
                *t+=0x0100;
            }
        }
    }
//    delete[] bt;

    for (int i=0; i<fw*fh; i++){
        if (resized_font[i]!=0){
            u8 n = resized_font[i]>>8;
            u8 a = resized_font[i]&0xff;
            int t = a*0x0f/n;
            resized_font[i]=t>0x0f?0x0f:t;
        }
    }

    if (outward==OUTWARD_TYPE_NORMAL){
        for (int i=0; i<fh; i++){
            for (int j=0; j<fw; j++){
                int alpha = resized_font[i*fw+j];
                if (alpha!=0){
                    data16[(posy+i)*this->width_p+posx+j] = color_bone&(0xfff0|alpha);
                }
            }
        }
    }else if (outward==OUTWARD_TYPE_SHADOW){
        for (int i=0; i<fh; i++){
            for (int j=0; j<fw; j++){
                int alpha = resized_font[i*fw+j];
                if (alpha!=0){
                    data16[(posy+i)*this->width_p+posx+j] = color_skin&(0xfff0|alpha);
                    if (alpha==15){
                        data16[(posy+i-1)*this->width_p+posx+j-1] = color_bone&(0xfff0|alpha);
                    }else{
                        u16 d = data16[(posy+i-1)*this->width_p+posx+j-1];
                        if (d==0){
                            data16[(posy+i-1)*this->width_p+posx+j-1] = color_bone&(0xfff0|alpha);
                        }else{
                            int r = ((color_bone&0xf000)*(alpha+1)+(color_skin&0xf000)*(15-alpha))>>4;
                            int g = ((color_bone&0x0f00)*(alpha+1)+(color_skin&0x0f00)*(15-alpha))>>4;
                            int b = ((color_bone&0x00f0)*(alpha+1)+(color_skin&0x00f0)*(15-alpha))>>4;
                            data16[(posy+i-1)*this->width_p+posx+j-1] = (r&0xf000)|(g&0x0f00)|(b&0x00f0)|0x0f;
                        }
                    }
                }
            }
        }
    }else if (outward==OUTWARD_TYPE_SURROUND){
        int fw2 = fw+2;
        int fh2 = fh+2;
//        float size2 = (float)fh2/font_height;
        u16* resized_font2 = new u16[fw2*fh2];
        memset(resized_font2, 0, fw2*fh2*2);
//        for (int i=0; i<font_height; i++){
//            bt[i] = i*size;
//        }
        for (int i=0; i<font_height; i++){
            for (int j=0; j<font_width; j++){
                u16* t1 = &resized_font2[bt[i]*fw2+bt[j]];
                u16* t2 = &resized_font2[(bt[i]+1)*fw2+bt[j]];
                u16* t3 = &resized_font2[(bt[i]+2)*fw2+bt[j]];
                u8 ts = src_font_buff[i*font_width+j];
                if (ts!=0){
                    t1[0]+=0x0303;
                    t1[1]+=0x0303;
                    t1[2]+=0x0303;
                    t2[0]+=0x0303;
                    t2[1]+=0x0303;
                    t2[2]+=0x0303;
                    t3[0]+=0x0303;
                    t3[1]+=0x0303;
                    t3[2]+=0x0303;
                }else{
                    t1[0]+=0x0100;
                    t1[1]+=0x0100;
                    t1[2]+=0x0100;
                    t2[0]+=0x0100;
                    t2[1]+=0x0100;
                    t2[2]+=0x0100;
                    t3[0]+=0x0100;
                    t3[1]+=0x0100;
                    t3[2]+=0x0100;
                }
            }
        }
        for (int i=0; i<fw2*fh2; i++){
            if (resized_font2[i]!=0){
                u8 n = resized_font2[i]>>8;
                u8 a = (resized_font2[i]&0xff)*2;
                int t = a*0x0f/n;
                resized_font2[i]=t>0x0f?0x0f:t;
            }
        }

        for (int i=0; i<fh2; i++){
            for (int j=0; j<fw2; j++){
                int alpha = resized_font2[i*fw2+j];
                if (alpha!=0){
                    data16[(posy+i-2)*this->width_p+posx+j-2] = color_skin&(0xfff0|alpha);
                }
//                *debuger<<alpha<<",";
            }
//            *debuger<<debuger->endl();
        }
        for (int i=0; i<fh; i++){
            for (int j=0; j<fw; j++){
                int alpha = resized_font[i*fw+j];
                if (alpha==15){
                    data16[(posy+i-1)*this->width_p+posx+j-1] = color_bone&(0xfff0|alpha);
                }else if (alpha>0){
                    u16 d = data16[(posy+i-1)*this->width_p+posx+j-1];
                    if (d==0){
                        data16[(posy+i-1)*this->width_p+posx+j-1] = color_bone&(0xfff0|alpha);
                    }else{
                        int r = ((color_bone&0xf000)*(alpha+1)+(color_skin&0xf000)*(15-alpha))>>4;
                        int g = ((color_bone&0x0f00)*(alpha+1)+(color_skin&0x0f00)*(15-alpha))>>4;
                        int b = ((color_bone&0x00f0)*(alpha+1)+(color_skin&0x00f0)*(15-alpha))>>4;
                        data16[(posy+i-1)*this->width_p+posx+j-1] = (r&0xf000)|(g&0x0f00)|(b&0x00f0)|0x0f;
                    }
                }
            }
        }
        delete[] resized_font2;
    }
    delete[] resized_font;
}
